package cn.tangsihai.es;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

public class ESTest {
    // 获取连接
    private static TransportClient getClient() throws UnknownHostException {
        Settings settings = Settings.builder()
                .put("client.transport.sniff", true).build();
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        return client;
    }

    /**
     * 添加索引
     * @throws UnknownHostException
     */
    @Test
    public void addTest () throws UnknownHostException {
        // 获取连接
        TransportClient client = getClient();
        // 创建索引
        IndexRequestBuilder indexRequestBuilder = client.prepareIndex("pethome2", "user2", "1");
        // 准备数据
        HashMap<String, String> map = new HashMap<>();
        map.put("id", "1");
        map.put("name", "小老弟");
        map.put("age", "18");
        // 添加文档
        IndexRequestBuilder source = indexRequestBuilder.setSource(map);
        // 获取文档
        IndexResponse indexResponse = source.get();
        System.out.println(indexResponse);
        // 关闭连接
        client.close();
    }

    /**
     * 获取索引
     * @throws UnknownHostException
     */
    @Test
    public void getTest () throws UnknownHostException {
        // 获取连接
        TransportClient client = getClient();
        // 获取文档
        GetRequestBuilder requestBuilder = client.prepareGet("pethome2", "user2", "1");
        // 执行操作
        GetResponse getFields = requestBuilder.get();
        // 获取文档中的数据
        System.out.println(getFields.getSource());
        // 关闭连接
        client.close();
    }

    /**
     * 修改索引
     * @throws UnknownHostException
     */
    @Test
    public void updateTest () throws UnknownHostException {
        // 获取连接
        TransportClient client = getClient();
        // 获取文档
        UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate("pethome2", "user2", "1");
        // 准备修改数据
        HashMap<String, String> map = new HashMap<>();
        map.put("name", "卧龙凤雏");
        map.put("id", "2");
        map.put("age", "23");
        // 添加修改数据到文档中，get()：执行该操作
        UpdateResponse updateRequestBuilder1 = updateRequestBuilder.setDoc(map).get();
        System.out.println("修改成功");
        // 关闭连接
        client.close();
    }

    /**
     * 删除索引
     * @throws UnknownHostException
     */
    @Test
    public void deleteTest () throws UnknownHostException {
        // 获取连接
        TransportClient client = getClient();
        // 删除对应索引，get()：执行操作
        DeleteResponse deleteRequestBuilder = client.prepareDelete("pethome2", "user2", "1").get();
        System.out.println("删除成功");
        // 关闭连接
        client.close();
    }

    /**
     * 综合查询
     * 查询name为“小老弟”，年龄在20--30之间的数据，从0开始分页，每页数据3条，安照年龄降序排序
     */
    @Test
    public void selectTest () throws UnknownHostException {
        // 获取连接
        TransportClient client = getClient();
        // 获取想要检索的索引
        SearchRequestBuilder searchBuilder = client.prepareSearch("pethome2");

        // 排序：安装年龄排序
        searchBuilder.addSort("age", SortOrder.DESC);

        // 分页
        // 设置起始页
        searchBuilder.setFrom(0);
        // 设置每页展示数据
        searchBuilder.setSize(3);

        // 查询条件 bool：组合查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // must：必须包含的查询条件，精确查询
        boolQuery.must(QueryBuilders.matchQuery("name", "小老弟"));
        // filter：可能包含的查询条件
        boolQuery.filter(QueryBuilders.matchQuery("name", "小老弟"))
                // 年龄在20-30之间的数据 模糊查询
                .filter(QueryBuilders.rangeQuery("age").gte(20).lte(30));
        // 将查询条件设置到索引中,get()：执行查询条件
        SearchResponse searchResponse = searchBuilder.setQuery(boolQuery).get();

        // 命中：从结果中拿到结果
        SearchHits hits = searchResponse.getHits();
        // 获取总命中数
        long totalHits = hits.getTotalHits();
        System.out.println(totalHits);
        // 获取命中列表
        SearchHit[] hits1 = hits.getHits();
        // 打印
        for (SearchHit s: hits1) {
            Map<String, Object> source = s.getSource();
            System.out.println(source);
        }
        // 关闭连接
        client.close();
    }
}
